package com.topc.others.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.EncryptUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.topc.base.exception.Asserts;
import com.topc.base.model.PageParams;
import com.topc.base.model.PageResult;
import com.topc.base.utils.PageUtils;
import com.topc.others.mapper.CompetitionInfoMapper;
import com.topc.others.mapper.CompetitionUserMidMapper;
import com.topc.others.model.dto.SaveCompetitionInfoDto;
import com.topc.others.model.enums.ApplyEnum;
import com.topc.others.model.enums.DifficultyEnum;
import com.topc.others.model.enums.TypeEnum;
import com.topc.others.model.po.CompetitionInfo;
import com.topc.others.model.po.CompetitionUserMid;
import com.topc.others.model.vo.CompetitionCheckInfoVo;
import com.topc.others.model.vo.CompetitionDetailShowVo;
import com.topc.others.model.vo.CompetitionInfoShowVo;
import com.topc.others.model.vo.CompetitionRankingShowVo;
import com.topc.others.service.ICompetitionInfoService;
import com.topc.others.service.ICompetitionUserMidService;
import com.topc.others.service.feign.CourseClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 竞赛信息 服务实现类
 * </p>
 *
 * @author Gogoing
 */
@Slf4j
@Service
public class CompetitionInfoServiceImpl extends ServiceImpl<CompetitionInfoMapper, CompetitionInfo> implements ICompetitionInfoService {

    @Autowired
    private CourseClient courseClient;

    @Autowired
    private ICompetitionUserMidService competitionUserMidService;

    @Autowired
    private CompetitionUserMidMapper competitionUserMidMapper;

    @Override
    public void saveCompetitionInfo(SaveCompetitionInfoDto saveCompetitionInfoDto) {
        CompetitionInfo competitionInfo = new CompetitionInfo();
        BeanUtil.copyProperties(saveCompetitionInfoDto, competitionInfo);
        boolean save = this.save(competitionInfo);
        if (!save) Asserts.fail("添加失败");
    }

    @Override
    public void deleteCompetitionInfoById(Long id) {
        LambdaQueryWrapper<CompetitionInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompetitionInfo::getId, id);
        boolean remove = this.removeById(queryWrapper);
        if (!remove) Asserts.fail("删除失败");
    }

    @Override
    public void updateCompetitionInfoById(Long id, Integer status) {
        LambdaUpdateWrapper<CompetitionInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CompetitionInfo::getStatus, status);
        updateWrapper.eq(CompetitionInfo::getId, id);
        boolean update = this.update(updateWrapper);
        if (!update)Asserts.fail("更新失败");
    }

    /**
     * TODO
     * @param pageParams
     * @param title
     * @return
     */
    @Override
    public PageResult<CompetitionInfoShowVo> getCompetitionInfoByPage(String userNumber,PageParams pageParams, String title) {
        //获取用户班级id列表
        List<Long> courseIds = courseClient.getCourseListByNumber(userNumber);
        System.out.println(courseIds);
        LambdaQueryWrapper<CompetitionInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select();
        //查询用户所在班级并且公开且未禁用的竞赛列表
        queryWrapper.notLike(CompetitionInfo::getStatus,-1)
                .eq(CompetitionInfo::getIsPublic,0)
                .in(CompetitionInfo::getGroupId,courseIds);
        if (!StringUtils.isEmpty(title)){
            queryWrapper.like(CompetitionInfo::getTitle, title);
        }
        Page<CompetitionInfo> page=this.page(pageParams.page(),queryWrapper);
        List<CompetitionInfoShowVo> collect = page.getRecords().stream()
                .map(competitionInfo -> {
                    CompetitionInfoShowVo competitionInfoShowVo = new CompetitionInfoShowVo();
                    competitionInfoShowVo.setId(competitionInfo.getId());
                    competitionInfoShowVo.setTitle(competitionInfo.getTitle());
                    competitionInfoShowVo.setStartTime(competitionInfo.getStartTime());
                    competitionInfoShowVo.setEndTime(competitionInfo.getEndTime());
                    competitionInfoShowVo.setDifficulty(Objects.requireNonNull(DifficultyEnum.getEnumByValue(competitionInfo.getDifficulty())).getText());
                    competitionInfoShowVo.setType(Objects.requireNonNull(TypeEnum.getEnumByValue(competitionInfo.getStatus())).getText());
                    return competitionInfoShowVo;
                })
                .collect(Collectors.toList());
        PageResult<CompetitionInfoShowVo> pageResult = PageUtils.pageToResult(page);
        pageResult.setItems(collect);
        return pageResult;
    }

    @Override
    public CompetitionDetailShowVo getDetailById(String userNumber, Long competitionId) {
        CompetitionInfo competitionInfo = this.getById(competitionId);
        Long groupId = competitionInfo.getGroupId();
        //查询用户是否存在于该班级
        int count = courseClient.searchUserCount(groupId, userNumber);
        if (count==0&&groupId!=0){
            Asserts.fail("您没有权限查看该比赛");
        }
        LambdaQueryWrapper<CompetitionUserMid> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(CompetitionUserMid::getStatus)
                .eq(CompetitionUserMid::getCompetitionId, competitionId)
                .eq(CompetitionUserMid::getUserNumber, userNumber);
        CompetitionUserMid competitionUserStatus = competitionUserMidService.getOne(queryWrapper);
        CompetitionDetailShowVo competitionDetailShowVo = new CompetitionDetailShowVo();
        if (ObjectUtils.isEmpty(competitionUserStatus)){
            competitionDetailShowVo.setStatus("未报名");
        }else{
            competitionDetailShowVo.setStatus(ApplyEnum.getEnumByValue(competitionUserStatus.getStatus()).getText());
        }
        competitionDetailShowVo.setTitle(competitionInfo.getTitle());
        competitionDetailShowVo.setId(competitionId);
        competitionDetailShowVo.setNotice(competitionInfo.getNotice());
        competitionDetailShowVo.setStartTime(competitionInfo.getStartTime());
        competitionDetailShowVo.setEndTime(competitionInfo.getEndTime());


        return competitionDetailShowVo;
    }

    @Override
    public Long getComposeId(Long competitionId) {
        LambdaQueryWrapper<CompetitionInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(CompetitionInfo::getComposeMid)
                .eq(CompetitionInfo::getId,competitionId);
        CompetitionInfo competitionInfo = this.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(competitionInfo)){
            return null;
        }
        return Long.valueOf(competitionInfo.getComposeMid());
    }

    @Override
    public CompetitionCheckInfoVo getCompetitionCheckInfo(Long competitionId, String userNumber) {
        CompetitionCheckInfoVo checkInfo =competitionUserMidMapper.getCheckInfo(competitionId,userNumber);
        return checkInfo;
    }

    @Override
    public List<CompetitionRankingShowVo> getRanking(Long competitionId) {
        List<CompetitionRankingShowVo> competitionRankingShowVos=competitionUserMidMapper.getCompetitionUserRanking(competitionId);
        List<String> userNumbers = competitionRankingShowVos.stream()
                .map(CompetitionRankingShowVo::getUserNumber)
                .collect(Collectors.toList());
        System.out.println(":==================================================="+userNumbers);
        List<String> names = courseClient.searchRankingNameList(userNumbers);
        for (int i = 0; i < competitionRankingShowVos.size(); i++){
            competitionRankingShowVos.get(i).setName(names.get(names.size()-1-i));
        }
        System.out.println(competitionRankingShowVos);
        return competitionRankingShowVos;
    }
}
